﻿// ****************************************************************
// Copyright 2012, Stephan Burguchev
// e-mail: me@sburg.net
// ****************************************************************
// *
using System;
using System.IO;
using System.Reflection;

namespace Updater.Utils
{
    /// <summary>
    ///     The class if enabled will attempt to load missing assemblies from the platform specific directory.
    /// </summary>
    public static class MultiPlatformDllLoader
    {
        private const string PlatformDir = "platform";
        private const string X64Dir = "x64";
        private const string X86Dir = "x86";

        private static bool _isEnabled;

        /// <summary>
        ///     Gets or sets a value indicating whether this <see cref="MultiPlatformDllLoader" />
        ///     will attempt to load missing assemblies from the platform specific directory.
        /// </summary>
        /// <value>
        ///     <c>true</c> if the missing assembly resolver is enabled; otherwise, <c>false</c>.
        /// </value>
        public static bool Enable
        {
            get
            {
                return _isEnabled;
            }
            set
            {
                lock (typeof(MultiPlatformDllLoader))
                {
                    if (_isEnabled != value)
                    {
                        if (value)
                        {
                            AppDomain.CurrentDomain.AssemblyResolve += resolver;
                        }
                        else
                        {
                            AppDomain.CurrentDomain.AssemblyResolve -= resolver;
                        }
                        _isEnabled = value;
                    }
                }
            }
        }

        private static Assembly resolver(object sender, ResolveEventArgs args)
        {
            string assemblyName = args.Name.Split(new[] { ',' }, 2)[0] + ".dll";
            string archSpecificPath = Path.Combine(
                PathHelper.StartupPath,
                PlatformDir,
                Environment.Is64BitProcess ? X64Dir : X86Dir,
                assemblyName);

            Assembly assembly = File.Exists(archSpecificPath)
                                    ? Assembly.LoadFile(archSpecificPath)
                                    : null;
            return assembly;
        }
    }
}
